// 云函数入口文件
const cloud = require('wx-server-sdk');

cloud.init();
const db = cloud.database();
const _ = db.command;
const $ = _.aggregate;

/**
 * @brief 根据用户信息context获得与用户相关的所有申请，包括
 * 用户申请其他队伍的记录和其他用户申请该用户队伍的记录
 * event参数说明：
 * 无
 * 返回值说明：
 * @return {Object} 
 *  errCode: 0-成功，1-用户未注册
 *  data: 实际数据列表，元素范例：
 *  {
    "_id": "f6e08a6462a2c33e0766f1db36cd4bf7",
    "members": [
      "o9Ifc5AmLZ2iXezR2lyOWh1Q1k-c",
      "o9Ifc5AmLZ2iXezR2lyOWh1Q1k-c"
    ],
    "time": "2022-6-10",
    "status": "accepted",
    "teamLeader": [
      {
        "_id": "f6e08a646270e741010d29dc1349b301",
        "nickName": "lyc",
        "_openid": "o9Ifc5BXNXoDvCX1dub-LLSK928I",
        "avatarUrl": "https://thirdwx.qlogo.cn/mmopen/vi_32/N9IHq7Qkjq6oorguhJG8YcMgZGibu4Sz8ujS1Ns6SaNYMicySHw4icOvvic58xAXrxNE2leNsiahS6lMcRU4iamwfXlw/132",
        "gender": 0
      }
    ],
    "applyerInfo": [
      {
        "_id": "b69f67c06270e80000f5a42d033ba24b",
        "_openid": "o9Ifc5AmLZ2iXezR2lyOWh1Q1k-c",
        "avatarUrl": "https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTLHicXLEqaqgibagHoBMVkhHLJc5Nf7IvrcPErUUx0GWLGfqQOGibtp3rw7PKmvfvE5e86GM8iae5tH5w/132",
        "gender": 0,
        "nickName": "jyx"
      }
    ]
  }
 */
// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext();
  const openid = wxContext.OPENID;
  const LIMIT = 100;

  // 检查用户是否注册
  var userInfo = await db.collection('user').where({
    _openid: openid
  }).get();
  if (userInfo.data.length == 0) {
    return {
      errCode: 1
    };
  }
  // 获取目标记录数量
  var count = await db.collection('application').aggregate()
    .lookup({
      from: 'post',
      localField: 'team',
      foreignField: '_id',
      as: 'team',
    })
    .replaceRoot({
      newRoot: $.mergeObjects([$.arrayElemAt(['$team', 0]), '$$ROOT'])
    })
    .match(_.or([{
      applyer: openid
    }, {
      _openid: openid
    }]))
    .count('targetCount')
    .end();
  count = count.list[0].targetCount;
  console.log('count', count);
  // 获取相关申请记录
  var tasks = [];
  for (var i = 0; i < count / LIMIT; i++) {
    var t = db.collection('application').aggregate()
      .lookup({ // 首先连接post集合，查询申请的队伍的信息
        from: 'post',
        let: {
          teamPostId: '$team'
        },
        pipeline: $.pipeline()
          .match(_.expr($.eq(['$_id', '$$teamPostId']))) // 连接条件 application.team=post._id
          .project({
            _id: 1,
            _openid: 1,
            name: 1,
            members: 1,
            title: 1
          })
          .done(),
        as: 'team',
      })
      .replaceRoot({ // 将连接post集合的查询结果merge进全部结果
        newRoot: $.mergeObjects([$.arrayElemAt(['$team', 0]), '$$ROOT'])
      })
      .match(_.or([{ // 在application集合中匹配openid
        applyer: openid
      }, {
        _openid: openid
      }]))
      .skip(i * LIMIT)
      .limit(LIMIT)
      .lookup({ // 连接user集合查询队伍发起者的信息
        from: 'user',
        let: {
          appOpenid: '$_openid'
        },
        pipeline: $.pipeline()
          .match(_.expr($.eq(['$_openid', '$$appOpenid']))) // 连接条件 applicaiton._openid=user._openid（application的_openid是上一次连接查询的结果）
          .project({
            _id: 1,
            _openid: 1,
            nickName: 1,
            avatarUrl: 1,
            gender: 1
          }).done(),
        as: 'teamLeader',
      })
      .lookup({ // 连接user集合查询申请者的信息
        from: 'user',
        let: {
          appOpenid: '$applyer'
        },
        pipeline: $.pipeline()
          .match(_.expr($.eq(['$_openid', '$$appOpenid']))) // 连接条件 applicaiton.applyer=user._openid
          .project({
            _id: 1,
            _openid: 1,
            nickName: 1,
            avatarUrl: 1,
            gender: 1
          }).done(),
        as: 'applyerInfo',
      })
      .project({ // 保留指定字段
        _id: 1,
        members: 1,
        name: 1,
        time: 1,
        status: 1,
        teamLeader: 1,
        applyerInfo: 1
      })
      .sort({ // 排序，按照申请时间降序
        time: -1
      })
      .end();
    tasks.push(t);
    console.log('task', i+1, 'launched');
  }
  // 等待所有任务
  var appRcds = (await Promise.all(tasks)).reduce((acc, cur) => {
    return {
      list: acc.list.concat(cur.list)
    };
  });
  return {
    data: appRcds.list,
    errCode: 0
  };
}